package com.jx.driving.protocol.terminal.codec;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 处理定长list对象
 * 
 * @author shenliuyang
 *
 *         2016年8月12日下午5:35:53
 */
public class LimitedListReaderWriter extends FieldReaderWriter {

	private ClassReaderWriter rw;

	public LimitedListReaderWriter(Field field, int size, int order) {
		super(field, size, order);
		Type type = field.getGenericType();
		if (!(type instanceof ParameterizedType)) {
			throw new IllegalArgumentException("field not parameterized " + field);
		}
		ParameterizedType pt = (ParameterizedType) type;
		try {
			rw = new ClassReaderWriter((Class<?>) pt.getActualTypeArguments()[0]);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void read(InputStream in, Object to) throws IOException {
		byte[] length = new byte[size];
		in.read(length);
		int head = 0;
		for (int i = 0; i < size; i++) {
			head <<= 8;
			head |= length[i] & 0xFF;
		}
		List<Object> list = new ArrayList<>(head);
		for (int i = 0; i < head; i++) {
			Object obj;
			try {
				obj = rw.read(in);
				list.add(obj);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		wrtietoField(to, list);
	}

	@Override
	public void write(OutputStream out, Object from) throws IOException {
		List<?> list = (List<?>) readFromField(from);
		if (list == null) {
			list = Collections.emptyList();
		}
		int len = list.size();
		if (size == 1) {
			out.write((byte) len);
		} else {
			ByteBuffer bb = ByteBuffer.allocate(2);
			bb.putShort((short) len);
			out.write(bb.array());
		}
		for (Object bean : list) {
			try {
				rw.write(out, bean);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}

}
